package GenericLearn;



import org.junit.jupiter.api.Test;

import java.util.*;

/**
 * @author Lenl
 * @version v1.0
 * @create 2021-06-05 16:38
 * @description 泛型的使用
 * 1.jdk5.0新增的特性
 * 2.在集合中使用泛型
 *      总结：
 *          ①集合接口和集合类在jdk5.0之后修改为带泛型的结构
 *          ②实例化集合类时，可以指明具体的泛型类型
 *          ③指明完之后，实例化类型就是确定的，更加安全
 *          ④注意点：泛型类型必须是类，不能是基本数据类型
 *          ⑤未指明时默认为Object类型
 *3.如何自定义泛型结构：泛型类、泛型接口、泛型方法
 *  泛型中可以有多个参数
 *
 */
public class GenericTest {
    @Test
    public void test1(){
        //未使用泛型时：
        //需求：存放学生的成绩
        ArrayList list=new ArrayList();
        list.add(100);
        list.add(98);
        //问题1：类型不安全
        list.add("tom");//线程不安全！
        //问题二：强转时可能会出问题

    }

    @Test
    public void test2(){
        //在集合中使用泛型的情况
        //泛型不能使用基本数据类型，得用包装类
        ArrayList<Integer> list=new ArrayList<Integer>();
        list.add(123);
        //list.add("123");//编译时会检查类型，保证数据安全
        list.add(321);
        for (Integer i : list){
            //不用强转了
            System.out.println(i);
        }
        //用迭代器
        Iterator<Integer> iterator=list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }

    //在集合中使用泛型：以HashMap为例
    @Test
    public void test3(){
        Map<String,Integer> map=new HashMap<>();
        map.put("tom",123);
        map.put("jey",122);
        map.put("ter",103);

        Set<Map.Entry<String,Integer>> set=map.entrySet();
        Iterator<Map.Entry<String,Integer>> iterator=set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
        for (Map.Entry<String,Integer> i : set){
            System.out.println(i.getKey()+":"+i.getValue());
        }
    }

    //泛型方法，要在前面加个<E>指明E是一个泛型
    //泛型方法可以声明为静态的，原因在于泛型参数是在调用时确定的
    public static <E>  List<E> copyFormArrayList(E[] arr){
        ArrayList<E> list=new ArrayList<>();
        for (E e:arr){
            list.add(e);
        }
        return list;
    }
}
